<!DOCTYPE html>
<html lang="zh_cn">
<head>
          <title>来玩魔王的咚</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta charset="utf-8" />
        <!-- twitter card metadata -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="/images/mowang.png">
<meta name="twitter:site" content="">
<meta name="twitter:title" content="Docker 资源限制">
<meta name="twitter:description" content="<p>内存：OOME，内存限制；CPU：CPU Share，CPU核数，CPU指定核心；压力测试：查询宿主机上的资源，下载用于压测的镜像，测试内存限制，测试CPU限制，测试CPU Share</p>">
        <!-- OG Tags -->
<meta property="og:url" content="/docker-resource-limitation.html"/>
<meta property="og:title" content="来玩魔王的咚 | Docker 资源限制" />
<meta property="og:description" content="<p>内存：OOME，内存限制；CPU：CPU Share，CPU核数，CPU指定核心；压力测试：查询宿主机上的资源，下载用于压测的镜像，测试内存限制，测试CPU限制，测试CPU Share</p>" />
        <!-- favicon -->
        <link rel="icon" type="image/png" href="/images/mowang.png">
        <!-- moment.js for date formatting -->
        <script src="/theme/js/moment.js"></script>
        <!-- css -->
        <link rel="stylesheet" type="text/css" href="/theme/css/main.css" />
        <!-- 左边的menu，如果页面高度不够，就跟着滚动，否则文章分类显示不全 -->
        <link rel="stylesheet" type="text/css" href="/theme/css/mycss/menu.css" />
		<script>
			
                /*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */
    
    (function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
                
                grunticon(["/theme/css/icons.data.svg.css", "/theme/css/icons.data.png.css", "/theme/css/icons.fallback.css"]);
            </script>
        <noscript><link href="/theme/css/icons.fallback.css" rel="stylesheet"></noscript>
        <!-- menu toggle javascript -->
        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", initMenu);
            
            function initMenu(){
                var menu = document.getElementById("menu");
                var menulink = document.getElementById("menu-link");
                menulink.addEventListener("click", function toggleMenu(){
                        window.event.preventDefault();
                        menulink.classList.toggle('active');
                        menu.classList.toggle('active');              
                    });
            };
        </script>
        <!-- 不蒜子 -->
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

    <meta name="description" content="<p>内存：OOME，内存限制；CPU：CPU Share，CPU核数，CPU指定核心；压力测试：查询宿主机上的资源，下载用于压测的镜像，测试内存限制，测试CPU限制，测试CPU Share</p>" />

    <meta name="tags" content="docker" />
  <!-- 替换部分base的样式，看文章时，要再宽一点，右边有很多空间可以撑开 -->
  <link rel="stylesheet" type="text/css" href="/theme/css/mycss/article.css" />

</head>
<body>
    <div role="banner" id="masthead">
        <header>
            <a href="/"><img src="/images/mowang.png" alt="McManus Logo"></a>
                <h1>来玩魔王的咚@骑士救兵</h1>
            <a href="#menu" id="menu-link">more stuff</a>
            <nav id="menu">
                <ul>
                        <li><a href="/tags">tags</a></li>
                            <li><a href="/category/cloud.html">Cloud</a></li>
                            <li class="active"><a href="/category/docker.html">Docker</a></li>
                            <li><a href="/category/go.html">Go</a></li>
                            <li><a href="/category/linux.html">Linux</a></li>
                            <li><a href="/category/python.html">Python</a></li>
                            <li><a href="/category/xue-xi-bi-ji.html">学习笔记</a></li>
                            <li><a href="/category/yun-wei-zi-dong-hua.html">运维自动化</a></li>
                </ul>
            </nav>
        </header>
    </div>
        <div class="page" role="main">
  <div class="article" role="article">
    <article>
        <footer>
            <a name="top"></a>
            <p>
              <time datetime=" 2020-07-22 17:00:00+08:00">
                <script>document.write(moment('2020-07-22 17:00:00+08:00').format('LL'));</script>
              </time>
              ~
              <time datetime=" 2020-07-22 17:00:00+08:00">
                <script>document.write(moment('2020-07-22 17:00:00+08:00').format('LL'));</script>
              </time>
            </p>
        </footer>
        <header>
          <h2>
            Docker 资源限制
          </h2>
        </header>
      <div class="content">
         <div class="toc">
<ul>
<li><a href="#nei-cun">内存</a><ul>
<li><a href="#oome">OOME</a></li>
<li><a href="#nei-cun-xian-zhi">内存限制</a></li>
</ul>
</li>
<li><a href="#cpu">CPU</a><ul>
<li><a href="#cpu-share">CPU Share</a></li>
<li><a href="#cpu-he-shu">CPU 核数</a></li>
<li><a href="#cpu-zhi-ding-he-xin">CPU 指定核心</a></li>
<li><a href="#qi-ta-cpu-can-shu">其他CPU参数</a></li>
</ul>
</li>
<li><a href="#ya-li-ce-shi">压力测试</a><ul>
<li><a href="#cha-xun-su-zhu-ji-shang-de-zi-yuan">查询宿主机上的资源</a></li>
<li><a href="#xia-zai-jing-xiang">下载镜像</a></li>
<li><a href="#ce-shi-nei-cun-xian-zhi">测试内存限制</a></li>
<li><a href="#ce-shi-cpu-xian-zhi">测试CPU限制</a></li>
<li><a href="#ce-shi-cpu-share">测试 CPU Share</a></li>
</ul>
</li>
</ul>
</div>
<blockquote>
<p>默认情况下，一个容器并没有资源限制，并且该容器可以使用内核调度的所有资源。Docke提供了在启动容器时设置一些参数来控制该容器使用的内存、CPU和block IO。  </p>
</blockquote>
<p>真正可以控制的只有内存和CPU。  </p>
<h3 id="nei-cun"><a class="toclink" href="#nei-cun">内存</a></h3>
<p>内存是不可压缩资源。  </p>
<h4 id="oome"><a class="toclink" href="#oome">OOME</a></h4>
<p>在Linxu系统中，如果内核探测到宿主机没有足够的内存来调用执行系统的某些重要功能的时候，那么会抛出一个OOME(Out Of Memory Exception:内存异常)杀死某些进程，以此来释放内存。<br>
一旦发生OOME，任何进程都有可能被杀死，包括docker daemon在内。为此，Docker特地调整了docker daemon的OOM优先级，防止其被杀死，但是容器的优先级没有被调整。在内存不足时，内核会根据自己的调度算法，为每个进程得出一个评分，然后杀死分数最高的进程来释放内存。<br>
可以在docker run的时候指定--oom-score-adj参数（默认为0）。这个是容器被杀死的优先级，会影响评分，值越大越容易被杀死。<em>这个参数只是影响最终的评分，优先杀死进程是看评分，参数小的可能计算后分数仍然最高，依然会被优先杀掉。</em><br>
可以指定–oom-kill-disable=true参数，指定一些特定的重要的容器禁止被OOM杀掉。  </p>
<div class="highlight"><pre><span></span><code>--oom-kill-disable               Disable OOM Killer
--oom-score-adj int              Tune host<span class="err">&#39;</span>s OOM preferences <span class="o">(</span>-1000 to <span class="m">1000</span><span class="o">)</span>
</code></pre></div>

<h4 id="nei-cun-xian-zhi"><a class="toclink" href="#nei-cun-xian-zhi">内存限制</a></h4>
<table>
<thead>
<tr>
<th align="left">选项</th>
<th align="left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">-m,--memory</td>
<td align="left">内存限制，格式是数字加单位，单位可以为 b,k,m,g。最小为4M</td>
</tr>
<tr>
<td align="left">--memory-swap</td>
<td align="left">内存+交换分区大小总限制。格式同上。必须比-m设置的大</td>
</tr>
<tr>
<td align="left">--memory-swappiness</td>
<td align="left">默认情况下，主机可以把容器使用的匿名页（anonymous page）swap 出来，你可以设置一个 0-100 之间的值，代表允许 swap 出来的比例</td>
</tr>
<tr>
<td align="left">--memory-reservation</td>
<td align="left">设置一个内存使用的 soft limit，如果 docker 发现主机内存不足，会执行 OOM 操作。这个值必须小于 --memory 设置的值</td>
</tr>
<tr>
<td align="left">--kernel-memory</td>
<td align="left">容器能够使用的 kernel memory 大小，最小值为 4m</td>
</tr>
<tr>
<td align="left">--oom-kill-disable</td>
<td align="left">是否运行 OOM 的时候杀死容器。只有设置了 -m，才可以把这个选项设置为 false，否则容器会耗尽主机内存，而且导致主机应用被杀死</td>
</tr>
</tbody>
</table>
<p><strong>--memory-swap参数</strong><br>
这个参数要结合-m一起生效，表格中的描述比较简单，是一般的用法。<br>
一般用法：比-m大，内存+交换分区大小总限制。<br>
禁用swap：和-m一样大，这样--memory和--memory-swap的限制是一样大，可用的swap资源为0，相当于禁用。<br>
默认设置：设置为0或者不设置，如果主机（Docker Host）启用了swap，则容器可用的swap为内存限制的2倍。<br>
无限制：设置为-1，如果主机（Docker Host）启用了swap，则容器可使用宿主机所有的swap资源。  </p>
<p><em>在容器内使用free命令，看到的swap空间没有体现出上面这些限制，没有参考价值。</em>  </p>
<h3 id="cpu"><a class="toclink" href="#cpu">CPU</a></h3>
<p>CPU是可压缩资源。  </p>
<p>默认情况下，每一个容器可以使用宿主机上的所有cpu资源。大多数系统使用的资源调度算法是CFS（完全公平调度器），它公平调度每一个工作进程。进程可以分2类：CPU密集型（低优先级）和IO密集型（高优先级）。系统内核实时监测系统进程，当某个进程占用cpu资源时间过长时，内核会调整该进程的优先级。<br>
docker 1.13 之后还支持realtime调度。  </p>
<p>有如下的3种CPU资源分配策略：</p>
<ol>
<li>按压缩方式比例分配</li>
<li>限定最多只能几个核</li>
<li>限定只能使用哪个或哪几个核</li>
</ol>
<table>
<thead>
<tr>
<th align="left">选项</th>
<th align="left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">-c, --cpu-shares int</td>
<td align="left">cpu资源提供给一组容器使用，组内的容器按比例使用cpu资源，当容器处于空闲状态时，cpu资源被负载大的容器占用，（按压缩方式比例分配），当空闲进行运行起来时，cpu资源会被分配到其他容器</td>
</tr>
<tr>
<td align="left">--cpus decimal</td>
<td align="left">指定 cpu的核心数量，这种方式直接限定了容器可用的cpu资源</td>
</tr>
<tr>
<td align="left">--cpuset-cpus string</td>
<td align="left">指定容器只能运行在哪个cpu核心上（绑定cpu）；核心使用0,1,2,3编号</td>
</tr>
</tbody>
</table>
<h4 id="cpu-share"><a class="toclink" href="#cpu-share">CPU Share</a></h4>
<p>docker 为容器设置 CPU share 的参数是 -c, --cpu-shares，它的值是一个整数。  </p>
<p>docker 允许用户为每个容器设置一个数字，代表容器的 CPU share，默认情况下每个容器的 share 是 1024。当主机上有多个容器运行时，每个容器占用的 CPU 时间比例为它的 share 在总额中的比例。举个例子，如果主机上有两个一直使用 CPU 的容器（为了简化理解，不考虑主机上其他进程），其 CPU share 都是 1024，那么两个容器 CPU 使用率都是 50%；如果把其中一个容器的 share 设置为 512，那么两者 CPU 的使用率分别为 67% 和 33%；如果删除 share 为 1024 的容器，剩下来容器的 CPU 使用率将会是 100%。  </p>
<p>总结下来，这种情况下，docker 会根据主机上运行的容器和进程动态调整每个容器使用 CPU 的时间比例。这样的好处是能保证 CPU 尽可能处于运行状态，充分利用 CPU 资源，而且保证所有容器的相对公平；缺点是无法指定容器使用 CPU 的确定值。  </p>
<h4 id="cpu-he-shu"><a class="toclink" href="#cpu-he-shu">CPU 核数</a></h4>
<p>从 1.13 版本之后，docker 提供了 --cpus 参数可以限定容器能使用的 CPU 核数。这个功能可以让我们更精确地设置容器 CPU 使用量，是一种更容易理解也因此更常用的手段。  </p>
<p>--cpus 后面跟着一个浮点数，代表容器最多使用的核数，可以精确到小数点二位，也就是说容器最小可以使用 0.01 核 CPU。比如，我们可以限制容器只能使用 1.5 核数 CPU。  </p>
<p>如果设置的 --cpus 值大于主机的 CPU 核数，docker 会直接报错。<br>
如果多个容器都设置了 --cpus，并且它们之和超过主机的 CPU 核数，并不会导致容器失败或者退出，这些容器之间会竞争使用 CPU，具体分配的 CPU 数量取决于主机运行情况和容器的 CPU share 值。也就是说 --cpus 只能保证在 CPU 资源充足的情况下容器最多能使用的 CPU 数，docker 并不能保证在任何情况下容器都能使用这么多的 CPU（因为这根本是不可能的）。  </p>
<h4 id="cpu-zhi-ding-he-xin"><a class="toclink" href="#cpu-zhi-ding-he-xin">CPU 指定核心</a></h4>
<p>Docker 允许调度的时候限定容器运行在哪个 CPU 上。可以通过 --cpuset-cpus 参数让容器只运行在某个或某几个核上。  </p>
<p>--cpuset-cpus、-cpus 参数可以和 -c, --cpu-shares 一起使用，限制容器只能运行在某些 CPU 核上，并且配置了使用率。  </p>
<p>限制容器运行在哪些核上并不是一个很好的做法，因为它需要事先知道主机上有多少 CPU 核，而且非常不灵活。除非有特别的需求，一般并不推荐在生产中这样使用。  </p>
<h4 id="qi-ta-cpu-can-shu"><a class="toclink" href="#qi-ta-cpu-can-shu">其他CPU参数</a></h4>
<table>
<thead>
<tr>
<th align="left">选项</th>
<th align="left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">--cpu-period int</td>
<td align="left">指定CFS调度的周期，一般与--cpu-quota一起使用。默认情况下周期为1 秒，以微秒为单位表示，一般使用默认值。1.13或者更高版本推荐使用 --cpus 标志代替。</td>
</tr>
<tr>
<td align="left">--cpu-quota int</td>
<td align="left">在CFS调度中容器一个周期的cpu时间配额，即每个--cpu-period周期容器可获得的cpu时间(微秒)，cpu-quota/cpu-period。1.13或者更高版本推荐使用 --cpus 标志代替。</td>
</tr>
</tbody>
</table>
<h3 id="ya-li-ce-shi"><a class="toclink" href="#ya-li-ce-shi">压力测试</a></h3>
<p>资源限制的演示。  </p>
<h4 id="cha-xun-su-zhu-ji-shang-de-zi-yuan"><a class="toclink" href="#cha-xun-su-zhu-ji-shang-de-zi-yuan">查询宿主机上的资源</a></h4>
<p>这里用了lscpu和free命令：</p>
<div class="highlight"><pre><span></span><code>$ lscpu
Architecture:          x86_64
CPU op-mode<span class="o">(</span>s<span class="o">)</span>:        <span class="m">32</span>-bit, <span class="m">64</span>-bit
Byte Order:            Little Endian
CPU<span class="o">(</span>s<span class="o">)</span>:                <span class="m">1</span>
On-line CPU<span class="o">(</span>s<span class="o">)</span> list:   <span class="m">0</span>
Thread<span class="o">(</span>s<span class="o">)</span> per core:    <span class="m">1</span>
Core<span class="o">(</span>s<span class="o">)</span> per socket:    <span class="m">1</span>
Socket<span class="o">(</span>s<span class="o">)</span>:             <span class="m">1</span>
NUMA node<span class="o">(</span>s<span class="o">)</span>:          <span class="m">1</span>
Vendor ID:             GenuineIntel
CPU family:            <span class="m">6</span>
Model:                 <span class="m">60</span>
Model name:            Intel<span class="o">(</span>R<span class="o">)</span> Core<span class="o">(</span>TM<span class="o">)</span> i7-4790K CPU @ <span class="m">4</span>.00GHz
Stepping:              <span class="m">3</span>
CPU MHz:               <span class="m">3999</span>.996
BogoMIPS:              <span class="m">7999</span>.99
Hypervisor vendor:     Microsoft
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU<span class="o">(</span>s<span class="o">)</span>:     <span class="m">0</span>
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm ssbd ibrs ibpb stibp fsgsbase bmi1 avx2 smep bmi2 erms invpcid xsaveopt spec_ctrl intel_stibp flush_l1d
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           936M        260M        340M        <span class="m">6</span>.7M        334M        592M
Swap:          <span class="m">1</span>.6G          0B        <span class="m">1</span>.6G
$ 
</code></pre></div>

<h4 id="xia-zai-jing-xiang"><a class="toclink" href="#xia-zai-jing-xiang">下载镜像</a></h4>
<p>可以在docker hub上搜索stress（压测）。<br>
下载镜像，运行查看帮助：</p>
<div class="highlight"><pre><span></span><code>$ docker pull lorel/docker-stress-ng
</code></pre></div>

<div class="highlight"><pre><span></span><code>$ docker run -it --rm lorel/docker-stress-ng
stress-ng, version <span class="m">0</span>.03.11

Usage: stress-ng <span class="o">[</span>OPTION <span class="o">[</span>ARG<span class="o">]]</span>
 --h,  --help             show <span class="nb">help</span>
......省略......
Example: stress-ng --cpu <span class="m">8</span> --io <span class="m">4</span> --vm <span class="m">2</span> --vm-bytes 128M --fork <span class="m">4</span> --timeout 10s

Note: Sizes can be suffixed with B,K,M,G and <span class="nb">times</span> with s,m,h,d,y
$ 
</code></pre></div>

<p>主要命令参数：</p>
<ul>
<li>--h,  --help: 默认启动容器就是这个命令参数</li>
<li>-c N, --cpu N: 启动N个子进程对CPU进行压测</li>
<li>-m N, --vm N: 启动N个进程对内存进行压测</li>
<li>--vm-bytes N: 每个子进程使用多少内存（默认256MB）</li>
</ul>
<h4 id="ce-shi-nei-cun-xian-zhi"><a class="toclink" href="#ce-shi-nei-cun-xian-zhi">测试内存限制</a></h4>
<p>查看lorel/docker-stress-ng里内存相关的参数说明：</p>
<div class="highlight"><pre><span></span><code> -m N, --vm N             start N workers spinning on anonymous mmap
       --vm-bytes N       allocate N bytes per vm worker <span class="o">(</span>default 256MB<span class="o">)</span>
</code></pre></div>

<p>默认每个worker是256MB的内存，这个保持默认。然后指定--vm，开启2个worker，并且限制容器的内存只能使用256MB，启动容器：</p>
<div class="highlight"><pre><span></span><code>$ docker run --name stress1 -it --rm -m 256m lorel/docker-stress-ng --vm <span class="m">2</span>
stress-ng: info: <span class="o">[</span><span class="m">1</span><span class="o">]</span> defaulting to a <span class="m">86400</span> second run per stressor
stress-ng: info: <span class="o">[</span><span class="m">1</span><span class="o">]</span> dispatching hogs: <span class="m">2</span> vm
</code></pre></div>

<p>这个终端已经被占用了，另起一个终端使用docker top命令查看容器内部正在运行的进程：</p>
<div class="highlight"><pre><span></span><code>$ docker top stress1
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                <span class="m">5922</span>                <span class="m">5907</span>                <span class="m">0</span>                   <span class="m">21</span>:06               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --vm <span class="m">2</span>
root                <span class="m">6044</span>                <span class="m">5922</span>                <span class="m">0</span>                   <span class="m">21</span>:06               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --vm <span class="m">2</span>
root                <span class="m">6045</span>                <span class="m">5922</span>                <span class="m">0</span>                   <span class="m">21</span>:06               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --vm <span class="m">2</span>
root                <span class="m">6086</span>                <span class="m">6044</span>                <span class="m">13</span>                  <span class="m">21</span>:06               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --vm <span class="m">2</span>
root                <span class="m">6097</span>                <span class="m">6045</span>                <span class="m">47</span>                  <span class="m">21</span>:06               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --vm <span class="m">2</span>
$ 
</code></pre></div>

<p>这里可以看一下PID和PPID，这里一共5个进程，一个父进程创建了2个子进程，这2个子进程又分别各创建了一个进程。  </p>
<p>另外还可以使用命令docker stats查看容器的资源实时使用的情况：</p>
<div class="highlight"><pre><span></span><code>$ docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
626f38c4a4ad        stress1             <span class="m">18</span>.23%              256MiB / 256MiB     <span class="m">100</span>.00%             656B / 0B           <span class="m">17</span>.7MB / <span class="m">9</span>.42GB     <span class="m">5</span>
</code></pre></div>

<p>这个是实时刷新的。  </p>
<h4 id="ce-shi-cpu-xian-zhi"><a class="toclink" href="#ce-shi-cpu-xian-zhi">测试CPU限制</a></h4>
<p>限制容器最大只能使用2核，然后同时开启8个CPU进行压测，使用下面的命令：</p>
<div class="highlight"><pre><span></span><code>docker run -it --rm --cpus <span class="m">2</span> lorel/docker-stress-ng --cpu <span class="m">8</span>
</code></pre></div>

<p>限制只用0.5核，开启4个CPU进行压测：</p>
<div class="highlight"><pre><span></span><code>$ docker run --name stress2 -it --rm --cpus <span class="m">0</span>.5 lorel/docker-stress-ng --cpu <span class="m">4</span>
stress-ng: info: <span class="o">[</span><span class="m">1</span><span class="o">]</span> defaulting to a <span class="m">86400</span> second run per stressor
stress-ng: info: <span class="o">[</span><span class="m">1</span><span class="o">]</span> dispatching hogs: <span class="m">4</span> cpu
</code></pre></div>

<p>另起一个终端使用docker top命令查看容器内部正在运行的进程：</p>
<div class="highlight"><pre><span></span><code>$ docker top stress2
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                <span class="m">7198</span>                <span class="m">7184</span>                <span class="m">0</span>                   <span class="m">22</span>:35               pts/0               <span class="m">00</span>:00:00            /usr/bin/stress-ng --cpu <span class="m">4</span>
root                <span class="m">7230</span>                <span class="m">7198</span>                <span class="m">12</span>                  <span class="m">22</span>:35               pts/0               <span class="m">00</span>:00:02            /usr/bin/stress-ng --cpu <span class="m">4</span>
root                <span class="m">7231</span>                <span class="m">7198</span>                <span class="m">12</span>                  <span class="m">22</span>:35               pts/0               <span class="m">00</span>:00:02            /usr/bin/stress-ng --cpu <span class="m">4</span>
root                <span class="m">7232</span>                <span class="m">7198</span>                <span class="m">12</span>                  <span class="m">22</span>:35               pts/0               <span class="m">00</span>:00:02            /usr/bin/stress-ng --cpu <span class="m">4</span>
root                <span class="m">7233</span>                <span class="m">7198</span>                <span class="m">12</span>                  <span class="m">22</span>:35               pts/0               <span class="m">00</span>:00:02            /usr/bin/stress-ng --cpu <span class="m">4</span>
$ 
</code></pre></div>

<p>一个父进程，创建了4个子进程。  </p>
<p>然后再用docker stats命令查看资源占用：</p>
<div class="highlight"><pre><span></span><code>$ docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
14a341dd23d1        stress2             <span class="m">50</span>.02%              <span class="m">13</span>.75MiB / <span class="m">908</span>.2MiB   <span class="m">1</span>.51%               656B / 0B           0B / 0B             <span class="m">5</span>
</code></pre></div>

<p>因为限制了0.5核，所以基本不会超过50%。  </p>
<h4 id="ce-shi-cpu-share"><a class="toclink" href="#ce-shi-cpu-share">测试 CPU Share</a></h4>
<p>开启3个容器，分别指定不同的--cpu-shares参数，不指定的话默认是1024：</p>
<div class="highlight"><pre><span></span><code>$ docker run --name stress3.1 -itd --rm --cpu-shares <span class="m">512</span> lorel/docker-stress-ng --cpu <span class="m">4</span>
800d756f76ca4cf20af9fa726349f25e29bc57028e3a1cb738906a68a87dcec4
$ docker run --name stress3.2 -itd --rm lorel/docker-stress-ng --cpu <span class="m">4</span>
4b88007191812b239592373f7de837c25f795877d314ae57943b5410074c6049
$ docker run --name stress3.3 -itd --rm --cpu-shares <span class="m">2048</span> lorel/docker-stress-ng --cpu <span class="m">4</span>
8f103395b6ac93d337594fdd1db289b6462e01c3a208dcd3788332458ec03b98
$ 
</code></pre></div>

<p>查看3个容器的CPU占用率：</p>
<div class="highlight"><pre><span></span><code>$ docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
800d756f76ca        stress3.1           <span class="m">14</span>.18%              <span class="m">14</span>.53MiB / <span class="m">908</span>.2MiB   <span class="m">1</span>.60%               656B / 0B           0B / 0B             <span class="m">5</span>
4b8800719181        stress3.2           <span class="m">28</span>.60%              <span class="m">15</span>.78MiB / <span class="m">908</span>.2MiB   <span class="m">1</span>.74%               656B / 0B           0B / 0B             <span class="m">5</span>
8f103395b6ac        stress3.3           <span class="m">56</span>.84%              <span class="m">15</span>.38MiB / <span class="m">908</span>.2MiB   <span class="m">1</span>.69%               656B / 0B           0B / 0B             <span class="m">5</span>
</code></pre></div>

<p>占用率基本就是1/2/4，符合期望。  </p>
      </div>
      <div class="back-to-top">
        <a href="/">HOME</a>
        <a href="#top">TOP</a>
      </div>
    </article>
  </div>
<!-- end article -->
<!-- 页面往下滚动一段之后才会显示TOC -->
<script>
  window.onscroll = function() {
    var tocbox = document.getElementsByClassName('toc')[0];
    var osTop = document.documentElement.scrollTop || document.body.scrollTop;
    var osWidth = document.documentElement.scrollWidth || document.body.scrollWidth;
    // console.log(osTop)
    if (osTop>300 && osWidth>865) {
      tocbox.style.display = "block"
    }
    if (osTop<300 || osWidth<865) {
      tocbox.style.display = "none"
    }
  }
</script>
                <footer>
                    <div class="icons">
                    </div>
                    <span id="busuanzi_container_page_pv" style="padding: 10px">本文阅读量<span id="busuanzi_value_page_pv"></span>次</span>
                    <span id="busuanzi_container_site_pv" style="padding: 10px">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
                    <span id="busuanzi_container_site_uv" style="padding: 10px">本站总访客数<span id="busuanzi_value_site_uv"></span>人</span>
                    <p>© <script>document.write(moment().format('YYYY'));</script> 749B</p>
                </footer>
        </div>
</body>
</html>